package com.androidlongs.pullrefreshrecyclerylib.view;
/**
 * Created by zhaolong on 2017/10/16.
 * 站在顶峰，看世界
 * 落在谷底，思人生
 */

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.LinearInterpolator;

/**
 * class infation
 */
public class PullLoadingView extends View {

    private Path mPath;
    private Path mDistPath;
    private int mViewWidth;
    private int mViewHeight;

    private Paint mPaint;
    private float mScaledDensity;
    private float mLength;
    private PathMeasure mPathMeasure;
    private Float mAnimatedValue = 0f;
    private ValueAnimator mValueAnimator;
    private ValueAnimator mValueAnimator2;
    private ValueAnimator mValueAnimator3;

    private ValueAnimator mValueAnimator5;
    private ValueAnimator mValueAnimator6;

    public PullLoadingView(Context context) {
        super(context);
    }

    public PullLoadingView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public PullLoadingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initFunction(context, attrs, defStyleAttr);

    }

    private int mRadius = 20;
    private int mStrokeWidth = 6;

    private void initFunction(Context context, AttributeSet attrs, int defStyleAttr) {

        mScaledDensity = context.getResources().getDisplayMetrics().scaledDensity;

        mRadius = (int) (mRadius * mScaledDensity);
        mStrokeWidth = (int) (mStrokeWidth * mScaledDensity);


    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);


        mValueAnimator = ValueAnimator.ofFloat(0f, 1f);
        mValueAnimator.setDuration(300);
        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mAnimatedValue = (Float) valueAnimator.getAnimatedValue();
                invalidate();
            }
        });

        mViewHeight = h;
        mViewWidth = w;


        mRadius = mViewWidth / 4;

        mPaint = new Paint();
        mPaint.setColor(Color.BLUE);
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(mStrokeWidth);

        mPath = new Path();
        mPath.moveTo(-mRadius, 0);
        mPath.lineTo(0, -mRadius);
        mPath.lineTo(mRadius, 0);
        mPath.lineTo(0, mRadius);
        mPath.lineTo(-(mRadius + mStrokeWidth / 4), -mStrokeWidth / 4);

        /**
         * 用这个构造函数是创建一个 PathMeasure 并关联一个 Path， 其实和创建一个空的 PathMeasure 后调用 setPath 进行关联效果是一样的，
         * 同样，被关联的 Path 也必须是已经创建好的，如果关联之后 Path 内容进行了更改，则需要使用 setPath 方法重新关联。
         * 该方法有两个参数，第一个参数自然就是被关联的 Path 了，
         * 第二个参数是用来确保 Path 闭合，如果设置为 true， 则不论之前Path是否闭合，都会自动闭合该 Path(如果Path可以闭合的话)。
         */
        /**
         * 不论 forceClosed 设置为何种状态(true 或者 false)， 都不会影响原有Path的状态，即 Path 与 PathMeasure 关联之后，之前的的 Path 不会有任何改变。
         forceClosed 的设置状态可能会影响测量结果，如果 Path 未闭合但在与 PathMeasure 关联的时候设置 forceClosed 为 true 时，测量结果可能会比 Path 实际长度稍长一点，获取到到是该 Path 闭合时的状态。
         */
        mPathMeasure = new PathMeasure(mPath, true);

        mDistPath = new Path();

        mLength = mPathMeasure.getLength();
        // 截取一部分存入dst中，并使用 moveTo 保持截取得到的 Path 第一个点的位置不变
        mPathMeasure.getSegment(0, mLength, mDistPath, true);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.translate(mViewWidth / 2, mViewHeight / 2);
        if (mLoadingType == 1) {
            mDistPath.reset();
            mPathMeasure.getSegment(0, mLength * (mCurrentCount * 1f / mTotalCount), mDistPath, true);
            canvas.drawPath(mDistPath, mPaint);
        } else if (mLoadingType == 2) {
            mDistPath.reset();
            mPathMeasure.getSegment(0, mLength, mDistPath, true);
            canvas.rotate(mAnimatedValue * 135);
            canvas.drawPath(mDistPath, mPaint);

        } else if (mLoadingType == 3) {
            //上
            canvas.drawLine((-mRadius * mAnimatedValue), -mRadius, (mRadius * mAnimatedValue), -mRadius, mPaint);
            //右
            canvas.drawLine(mRadius, -mRadius * mAnimatedValue, mRadius, mRadius * mAnimatedValue, mPaint);
            //下
            canvas.drawLine((-mRadius * mAnimatedValue), mRadius, (mRadius * mAnimatedValue), mRadius, mPaint);
            //左
            canvas.drawLine(-mRadius, -mRadius * mAnimatedValue, -mRadius, mRadius * mAnimatedValue, mPaint);
        } else if (mLoadingType == 4) {

            canvas.rotate(mAnimatedValue * 360);

            //上
            canvas.drawLine((-mRadius * 0.3f), -mRadius, (mRadius * 0.3f), -mRadius, mPaint);
            //右
            canvas.drawLine(mRadius, -mRadius * 0.3f, mRadius, mRadius * 0.3f, mPaint);
            //下
            canvas.drawLine((-mRadius * 0.3f), mRadius, (mRadius * 0.3f), mRadius, mPaint);
            //左
            canvas.drawLine(-mRadius, -mRadius * 0.3f, -mRadius, mRadius * 0.3f, mPaint);
        } else if (mLoadingType == 5) {

            float flag = mRadius * mAnimatedValue;

            //上
            canvas.drawLine((-mRadius * 0.3f), -flag, (mRadius * 0.3f), -flag, mPaint);
            //右
            canvas.drawLine(flag, -mRadius * 0.3f, flag, mRadius * 0.3f, mPaint);
            //下
            canvas.drawLine((-mRadius * 0.3f), flag, (mRadius * 0.3f), flag, mPaint);
            //左
            canvas.drawLine(-flag, -mRadius * 0.3f, -flag, mRadius * 0.3f, mPaint);
        } else if (mLoadingType == 6) {
            canvas.drawLine(0, mRadius / 2, -mRadius * mAnimatedValue * 0.5f, (mRadius - mRadius * mAnimatedValue), mPaint);
            canvas.drawLine(0, mRadius / 2, mRadius * mAnimatedValue, (mRadius - (mRadius + mRadius / 4) * mAnimatedValue), mPaint);

        }
    }

    /**
     * 1 下拉状态
     * 2 从下拉状态 向 加载中状态 过渡 1
     * 3 从过渡状态1 向 加载中状态 过渡 2
     * 4 刷新状态
     * 5 从刷新状态 到 结束状态的过渡
     * 6 结束状态
     */
    private int mLoadingType = 1;
    private int mTotalCount;

    public void setTotalCount(int totalCount) {
        mTotalCount = totalCount;
        mCurrentCount = 0;
        invalidate();
    }

    private int mCurrentCount;

    public void setCurrentCount(int currentCount) {
        mLoadingType = 1;
        mCurrentCount = Math.abs(currentCount);
        invalidate();
    }

    public void setLoadingShow() {

        mLoadingType = 2;

        if (mValueAnimator5 != null) {
            mValueAnimator5.cancel();
            mValueAnimator5.removeAllUpdateListeners();
        }
        if (mValueAnimator6 != null) {
            mValueAnimator6.cancel();
            mValueAnimator6.removeAllUpdateListeners();
        }

        if (mValueAnimator3 != null) {
            mValueAnimator3.cancel();
            mValueAnimator3.removeAllUpdateListeners();
        }
        if (mValueAnimator2 != null) {
            mValueAnimator2.cancel();
            mValueAnimator2.removeAllUpdateListeners();
        }
        if (mValueAnimator != null) {
            mValueAnimator.cancel();
            mValueAnimator.removeAllUpdateListeners();
        }
        mValueAnimator3 = ValueAnimator.ofFloat(0f, 1f);
        mValueAnimator3.setDuration(300);
        //mValueAnimator3.setInterpolator(new LinearInterpolator());
        mValueAnimator3.setRepeatCount(Integer.MAX_VALUE);
        mValueAnimator3.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mAnimatedValue = (Float) valueAnimator.getAnimatedValue();
                Log.d("recy","value animatior 3") ;
                invalidate();
            }
        });

        mValueAnimator2 = ValueAnimator.ofFloat(1f, 0.3f);
        mValueAnimator2.setDuration(300);
        mValueAnimator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mAnimatedValue = (Float) valueAnimator.getAnimatedValue();
                invalidate();
            }
        });
        mValueAnimator2.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {

            }

            @Override
            public void onAnimationEnd(Animator animator) {
                mLoadingType = 4;
                mValueAnimator3.start();
            }

            @Override
            public void onAnimationCancel(Animator animator) {

            }

            @Override
            public void onAnimationRepeat(Animator animator) {

            }
        });

        mValueAnimator = ValueAnimator.ofFloat(0f, 1f);
        mValueAnimator.setDuration(300);
        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mAnimatedValue = (Float) valueAnimator.getAnimatedValue();
                invalidate();
            }
        });
        mValueAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {

            }

            @Override
            public void onAnimationEnd(Animator animator) {

                mLoadingType = 3;
                mValueAnimator2.start();
            }

            @Override
            public void onAnimationCancel(Animator animator) {

            }

            @Override
            public void onAnimationRepeat(Animator animator) {

            }
        });
        mValueAnimator.start();

    }


    /**
     * 结束刷新
     * 状态 从 刷新中 4 -- 过渡到 5
     * 从 5  过渡到 6  绘制对钩的过程
     */

    public void stopLoading() {

        if (mValueAnimator3 != null) {
            mValueAnimator3.cancel();
            mValueAnimator3.removeAllUpdateListeners();
        }
        if (mValueAnimator5 != null) {
            mValueAnimator5.cancel();
        }
        if (mValueAnimator6 != null) {
            mValueAnimator6.cancel();
        }

        if (mValueAnimator2 != null) {
            mValueAnimator2.cancel();
        }
        if (mValueAnimator != null) {
            mValueAnimator.cancel();
        }

        mLoadingType = 5;
        mValueAnimator5 = ValueAnimator.ofFloat(0f, 1f);
        mValueAnimator5.setDuration(300);
        mValueAnimator5.setRepeatCount(0);
        mValueAnimator5.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mAnimatedValue = (Float) valueAnimator.getAnimatedValue();
                invalidate();
            }
        });
        mValueAnimator5.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {
            }

            @Override
            public void onAnimationEnd(Animator animator) {

            }

            @Override
            public void onAnimationCancel(Animator animator) {

            }

            @Override
            public void onAnimationRepeat(Animator animator) {

            }
        });


        mValueAnimator6 = ValueAnimator.ofFloat(1f, 0f);
        mValueAnimator6.setDuration(300);
        mValueAnimator6.setRepeatCount(0);
        mValueAnimator6.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mAnimatedValue = (Float) valueAnimator.getAnimatedValue();
                invalidate();
            }
        });
        mValueAnimator6.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {

            }

            @Override
            public void onAnimationEnd(Animator animator) {

                mLoadingType = 6;
                mValueAnimator5.start();
            }

            @Override
            public void onAnimationCancel(Animator animator) {

            }

            @Override
            public void onAnimationRepeat(Animator animator) {

            }
        });
        mValueAnimator6.start();
    }
}
